<?php

ptaste();

class SiteObject implements ISiteChild
{
  private $jeng_site=null;
  private $logr=null;
  
  function __construct($site,$logger=null)
  {
    $this->jeng_site=$site;
	$this->logr=($logger!=null)?$logger:$site->logger();
  }

  function site()
  {
    return $this->jeng_site;
  }
  
  function logger()
  {
    return $this->logr;
  }
}

class Site implements ISite
{
	private $cdb=null;
	private $dbs=array(null,null,null);
	private $fconf=null;
	private $futils=null;
	private $f3dparty=null;
	private $logr=null;
	private $cur_page=null;
	const DB_SITE=0;
	const DB_JENG=1;
	const DB_COMMON=2;
	
	public function __construct()
	{
		if (session_id()=="")
			session_start();
	}
	
	public function db()
	{
		if (!$this->cdb)
			$this->cdb=$this->site_db();
		return $this->cdb;
	}
	
	public function site_db()
	{
	  if ($this->dbs[0]==null)
			$this->dbs[0]=new DBConnection($this,$this->logger(),$this->conf()->get('site_db_host'),$this->conf()->get('site_db_user'),$this->conf()->get('site_db_password'),$this->conf()->get('site_db_database'));
	  return $this->dbs[0];
	}
	
	public function jeng_db()
	{
	  if ($this->dbs[1]==null)
			$this->dbs[1]=new DBConnection($this,$this->logger(),$this->conf()->get('jeng_db_host'),$this->conf()->get('jeng_db_user'),$this->conf()->get('jeng_db_password'),$this->conf()->get('jeng_db_database'));
	  return $this->dbs[1];
	}
	
	public function common_db()
	{
	  if ($this->dbs[2]==null)
			$this->dbs[2]=new DBConnection($this,$this->logger(),$this->conf()->get('common_db_host'),$this->conf()->get('common_db_user'),$this->conf()->get('common_db_password'),$this->conf()->get('common_db_database'));
	  return $this->dbs[2];
	}
	
	public function add_db($host,$user,$password,$dbname)
	{
		$res=count($this->dbs);
		$this->dbs[$res]=new DBConnection($this,$this->logger(),$host,$user,$password,$dbname);
		return $res;
	}
	
	public function del_db($id)
	{
	  if ($id>2 && $id<count($this->dbs))
	    $this->dbs[$id]=null;
	}
	
	public function select_db($id)
	{
	  if ($id>=count($this->dbs))
	    return null;
	  $this->cdb=$this->dbs[$id];
	  return $this->cdb;
	}
	
	public function conf()
	{
	  global $jeng_path;
		if (!$this->fconf)
		{
			$this->fconf=new ConfigHolder($this);
			$this->fconf->set('jeng_engine_path',$jeng_path);
			$this->fconf->process($this->fconf->get('jeng_engine_path')."/config/jeng_config.xml");
		}
		return $this->fconf;
	}
	
	public function utils()
	{
	  if (!$this->futils)
	    $this->futils=new JEngUtils($this);
	  return $this->futils;
	}
	
	public function party()
	{
	  if (!$this->f3dparty)
	    $this->f3dparty=new JEng3dParty($this);
	  return $this->f3dparty;
	}

	function emptyXML($rootnode="result")
	{
		$doc=new DOMDocument("1.0","utf-8");
		$doc->encoding="utf-8";
		$root=$doc->createElement($rootnode);
		$doc->appendChild($root);
		return $doc;
	}
	
	public function logger()
	{
	  if (!$this->logr)
	  {
	    if ($this->conf()->has("log_file"))
		{
			$this->logr=new JEngLogger($this->conf()->get("log_file"),$this->conf()->get("log_level"));
		}else
			$this->logr=new JEngNullLogger();
	  }
	  return $this->logr;
	}
	
	public function page()
	{
	  if (!$this->cur_page)
	  {
		$this->cur_page=0;
		$qs=$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING'];
	    $res=$this->common_db()->queryf("SELECT id FROM pages WHERE site=%d AND '%s' LIKE addr ORDER BY LENGTH(addr) DESC;",$this->conf()->get('site_id'),$qs);
		if ($res)
		{
			$rw=$res->next();
			$this->cur_page=$rw[0];
		}
	  }
	  return $this->cur_page;
	}
	
}

abstract class JEngPagePart extends SiteObject implements IJXmlProducer
{
  function __construct($site,$logger=null)
  {
    parent::__construct($site,$logger);
  }
  
  function prepare()
  {
  }
  
  abstract function onRender();
  
  function render()
  {
    $this->prepare();
	return $this->onRender();
  }
  
  static function s_render()
  {
  }
}

class JEngObjContainer extends SiteObject implements IJXmlProducer
{
  private $objs=array();
  private $xml=null;

  function __construct($site,$xml=null,$logger=null)
  {
    parent::__construct($site,$logger);
	if ($xml)
	  $this->xml=$xml;
  }
  
  function prepare()
  {
  }
  
  function onRender($xml)
  {
    return $xml;
  }
  
  function render()
  {
    $this->prepare();
	if (!$this->xml)
	  $this->xml=$this->getContainerXml();
	if (!$this->xml)
	  return $this->site()->emptyXML("result");
	foreach($this->objs as $nm=>$vl)
	{
	  $xm=$vl->render();
	  $this->xml=JEngXCombiner::s_render($this->xml,$xm,$nm,$nm);
	}
	$this->xml=$this->onRender($this->xml);
	return $this->xml;
  }
  
  static function s_render()
  {
  }
  
  function add($name,$obj)
  {
	$this->objs[$name]=$obj;
  }
  
  function getContainerXml()
  {
	return null;
  }
  
}

class JEngPage extends Site
{
	public $doc=null;
	public $inc_path="/inc";
	public $page_doc=false;
	public $page_xslt=false;
	public $page_xml=false;
	public $header_doc=false;
	public $head_doc=false;
	public $left_doc=false;
	public $right_doc=false;
	public $bottom_doc=false;
	
	function __construct()
	{
	  parent::__construct();
	}
	
	function render_all()
	{
	  $this->doc=$this->render_page();
	  $header=$this->render_header();
	  $this->doc=JEngXCombiner::s_render($this->doc,$header,"jeng_header","header");
	  $head=$this->render_head();
	  $this->doc=JEngXCombiner::s_render($this->doc,$head,"jeng_head","head");
	  $left=$this->render_left();
	  $this->doc=JEngXCombiner::s_render($this->doc,$left,"jeng_left","left");
	  $body=$this->render_body();
	  $this->doc=JEngXCombiner::s_render($this->doc,$body,"jeng_body","body");
	  $right=$this->render_right();
	  $this->doc=JEngXCombiner::s_render($this->doc,$right,"jeng_right","right");
	  $bottom=$this->render_bottom();
	  $this->doc=JEngXCombiner::s_render($this->doc,$bottom,"jeng_bottom","bottom");
	}	
	
	function render_page()
	{
	   if ($this->page_doc && file_exists($this->page_doc))
	   {
	     require_once($this->page_doc);
		 $obj=new Page($this);
		 return $obj->render();
	   }
	   if (!$this->page_xslt && $this->page_xml)
	     return $this->page_xml;
	   if ($this->page_xslt)
	   {
		if (!$this->page_xml)
			$this->page_xml=$this->emptyXML("page");
		return JEngXSLTXslFile::s_render($this->page_xml,$this->page_xslt);
	   }
	   return $this->emptyXML("page");
	}
	
	function render_header()
	{
	   if ($this->header_doc && file_exists($this->header_doc))
	   {
	     require_once($this->header_doc);
		 $obj=new Header($this);
		 return $obj->render();
	   }
	   return $this->emptyXML("header");
	}
	
	function render_head()
	{
	   if ($this->head_doc && file_exists($this->head_doc))
	   {
	     require_once($this->head_doc);
		 $obj=new Head($this);
		 return $obj->render();
	   }
	   return $this->emptyXML("head");
	}
	
	function render_bottom()
	{
	   if ($this->bottom_doc && file_exists($this->bottom_doc))
	   {
	     require_once($this->bottom_doc);
		 $obj=new Bottom($this);
		 return $obj->render();
	   }
	   return $this->emptyXML("bottom");
	}

	function render_right()
	{
	   if ($this->right_doc && file_exists($this->right_doc))
	   {
	     require_once($this->right_doc);
		 $obj=new Right($this);
		 return $obj->render();
	   }
	   return $this->emptyXML("right");
	}
	
	function render_left()
	{
	   if ($this->left_doc && file_exists($this->left_doc))
	   {
	     require_once($this->left_doc);
		 $obj=new Left($this);
		 return $obj->render();
	   }
	   return $this->emptyXML("left");
	}
	
	function getBodyXml()
	{
	  return $this->emptyXML("body");
	}
	
	function getBodyXslt()
	{
	  return null;
	}
	
	function render_body()
	{
	   $xsl=$this->getBodyXslt();
	   if (!$xsl) return $this->getBodyXml();
	   return JEngXSLTXslFile::s_render($this->getBodyXml(),$xsl);
	}	
	
	function prepare_paths()
	{
	}
	
	function prepare()
	{
	}
	
	function prerender()
	{
	  return null;
	}
	
	function render()
	{
		$this->prepare_paths();
		$this->head_doc=$this->conf()->get("site_path").$this->inc_path."/head.php";
		$this->bottom_doc=$this->conf()->get("site_path").$this->inc_path."/bottom.php";
		$this->left_doc=$this->conf()->get("site_path").$this->inc_path."/left.php";
		$this->right_doc=$this->conf()->get("site_path").$this->inc_path."/right.php";
		$this->header_doc=$this->conf()->get("site_path").$this->inc_path."/header.php";
		$this->page_xslt=$this->conf()->get("site_path").$this->inc_path."/xslt/page.xsl";
		$this->prepare();
		$box=$this->prerender();
		if ($box)
		  return $box;
		$this->render_all();
		$this->utils()->gwtHelper()->addgwt(null);
		return $this->doc->saveXML();
	}
}

class JEngUser extends SiteObject implements IUser
{
  public $uid=0;
  public $uname=null;
  public $ufullname=null;
  public $ugroup=null;
  public $ugroupid=null;
  public $urights=null;
  public $ustatus=null;
  public $uemail=null;
  
  function __construct($site,$logger=null)
  {
    parent::__construct($site,$logger);
  }
  
  function set_user($id,$name,$fullname,$group,$gid,$rights,$email,$status)
  {
    $this->uid=$id;
	$this->uname=$name;
	$this->ufullname=$fullname;
	$this->ugroup=$group;
	$this->ugroupid=$gid;
	$this->urights=$rights;
	$this->uemail=$email;
	$this->ustatus=$status;
  }
  
  function id()
  {
    return $this->uid;
  }
  function name()
  {
    return $this->uname;
  }
  function fullName()
  {
    return $this->ufullname;
  }
  function group()
  {
    return $this->ugroup;
  }
  function groupId()
  {
    return $this->ugroupid;
  }
  function status()
  {
    return $this->ustatus;
  }
  function eMail()
  {
    return $this->uemail;
  }
  function rights()
  {
    return $this->urights;
  }
  function can($right)
  {
	if ($this->rights()=="*")
	  return true;
	$ur=strtoupper($right);
	//$this->site()->logger()->info("ur=%s in %s",$ur,$this->rights());
    return !((strpos($this->rights(),$right)===false) && (strpos($this->rights(),$ur)===false));
  }
}

abstract class JEngAuth extends SiteObject implements IAuth
{
  function __construct($site,$logger=null)
  {
     parent::__construct($site,$logger);
  }
  
  function authenticate()
  {
  }
  function doAuth()
  {
  }
  function logout($user)
  {
  }
}

class JEngMayAuthPage extends JEngPage
{
  public $suser=null;
  public $auth_doc=null;
  
  function __construct()
  {
    parent::__construct();
  }
  
  function user()
  {
    return $this->suser;
  }
  
  function get_auth()
  {
    $auth=null;
	if ($this->auth_doc && file_exists($this->auth_doc))
	{
	    require_once($this->auth_doc);
		$auth=new Auth($this);
	}else
		$auth=new JEngStdAuth($this);
	return $auth;
  }
  
  function prerender()
  {
	$auth=$this->get_auth();
    $this->suser=$auth->authenticate();
	return parent::prerender();
  }
  
  function render()
  {
	$this->auth_doc=$this->conf()->get("site_path").$this->inc_path."/auth.php";
	return parent::render();
  }

  function logout()
  {
	$auth=$this->get_auth();
    $this->suser=$auth->authenticate();
	if ($this->suser && $auth)
		$auth->logout($this->user());
  }  
}

class JEngAuthPage extends JEngPage
{
  public $suser=null;
  public $auth_doc=null;
  
  
  function __construct()
  {
    parent::__construct();
  }
  
  function user()
  {
    return $this->suser;
  }
  
  function get_auth()
  {
    $auth=null;
	if ($this->auth_doc && file_exists($this->auth_doc))
	{
	    require_once($this->auth_doc);
		$auth=new Auth($this);
	}else
		$auth=new JEngStdAuth($this);
	return $auth;
  }
  
  function prerender()
  {
	$auth=$this->get_auth();
    $this->suser=$auth->authenticate();
	if (!$this->user())
	{
	  return $auth->doAuth();
	}
	return parent::prerender();
  }
  
  function render()
  {
	$this->auth_doc=$this->conf()->get("site_path").$this->inc_path."/auth.php";
	return parent::render();
  }
  
  function logout()
  {
	$auth=$this->get_auth();
    $this->suser=$auth->authenticate();
	if ($this->suser)
		$auth->logout($this->user());
  }  
}

class JEngAuthPageByRights extends JEngAuthPage
{
  public $right=null;
  
  function __construct($right)
  {
    $this->right=$right;
    parent::__construct();
  }
  
  function prerender()
  {
     $res=parent::prerender();
	 if ($res==null)
	 {
	   if ($this->user()->can($this->right))
	     return null;
	   $res="ERROR: permission denied!!!";
	 }
	 return $res;
  }
}

class JEngService extends Site implements IJXmlProducer
{
  function __construct()
  {
   parent::__construct();
  }
  
  function prepare()
  {
  }

  function renderXml()
  {
    return $this->emptyXML();
  }
  
  function render()
  {
    $this->prepare();
	$xml=$this->renderXml();
	return $xml->saveXML();
  }
  
  static function s_render()
  {
  }
}


class JEngMayAuthService extends JEngService
{
}

class JEngAuthService extends JEngService
{
  public $inc_path="/inc";
  public $suser=null;
  public $auth_doc=null;
  
  function user()
  {
    return $this->suser;
  }
  
  function get_auth()
  {
    $auth=null;
	if ($this->auth_doc && file_exists($this->auth_doc))
	{
	    require_once($this->auth_doc);
		$auth=new Auth($this);
	}else
		$auth=new JEngStdServiceAuth($this);
	return $auth;
  }
  
  function prerender()
  {
    return null;
  }
  
  function render()
  {
	$this->auth_doc=$this->conf()->get("site_path").$this->inc_path."/auth.php";
	$this->prepare();
	$auth=$this->get_auth();
    $this->suser=$auth->authenticate();
	if (!$this->user())
	{
	   $doc=$this->emptyXML("AuthenticationFailed");
	   return $doc->saveXML();
	}
	$box=$this->prerender();
	if ($box)
	  return $box->saveXML();
	$xml=$this->renderXml();
	return $xml->saveXML();
  }
  
  function logout()
  {
	$auth=$this->get_auth();
	$auth->logout($this->user());
  }  

}

class JEngAuthServiceByRights extends JEngAuthService
{
	public $right=null;
	
	function __construct($right)
	{
	  parent::__construct();
	  $this->right=$right;
	}
	
	function prerender()
	{
	  if ($this->user()->can($this->right))
	    return null;
	  $doc=$this->emptyXML("result");
	  $this->utils()->xmlHelper()->appendAttribute($doc->documentElement,"r","1");
	  $this->utils()->xmlHelper()->appendAttribute($doc->documentElement,"d","Permission denied");
	  return $doc;
	}
	
}

?>